package util

import (
	"fmt"
	"strings"
	"time"

	"kwdb-import/pkg/converter"
	"kwdb-import/pkg/executor"
	"kwdb-import/pkg/parser"
	"kwdb-import/pkg/validator"
)

// Importer KWDB导入器
type Importer struct {
	connectionString string
	username         string
	password         string
	parser           *parser.MySQLParser
	converter        *converter.MySQLToKWDBConverter
	validator        *validator.SQLValidator
	executor         *executor.StatementExecutor
}

// ImportStats 导入统计信息
type ImportStats struct {
	TotalStatements   int
	SuccessStatements int
	FailedStatements  int
	Warnings          []string
	Errors            []string
	StartTime         time.Time
	EndTime           time.Time
	Duration          time.Duration
	StatementStats    map[string]int
}

// NewImporter 创建新的导入器
func NewImporter(connection, username, password string) *Importer {
	return &Importer{
		connectionString: connection,
		username:         username,
		password:         password,
		parser:           parser.NewMySQLParser(),
		converter:        converter.NewMySQLToKWDBConverter(),
		validator:        validator.NewSQLValidator(),
	}
}

// Import 执行导入操作
func (imp *Importer) Import(sqlFilePath string) error {
	stats := &ImportStats{
		StartTime:      time.Now(),
		StatementStats: make(map[string]int),
		Warnings:       make([]string, 0),
		Errors:         make([]string, 0),
	}

	fmt.Println("=== KWDB异构数据库快速迁移导入工具 ===")
	fmt.Printf("开始时间: %s\n", stats.StartTime.Format("2006-01-02 15:04:05"))
	fmt.Printf("SQL文件: %s\n", sqlFilePath)
	fmt.Println()

	// 步骤1: 验证连接参数
	fmt.Println("步骤1: 验证连接参数...")
	if err := imp.validateConnectionParams(); err != nil {
		return fmt.Errorf("连接参数验证失败: %v", err)
	}
	fmt.Println("✓ 连接参数验证通过")

	// 步骤2: 解析SQL文件
	fmt.Println("\n步骤2: 解析SQL文件...")
	statements, err := imp.parser.Parse(sqlFilePath)
	if err != nil {
		return fmt.Errorf("解析SQL文件失败: %v", err)
	}
	stats.TotalStatements = len(statements)
	fmt.Printf("✓ 成功解析 %d 条SQL语句\n", len(statements))

	// 步骤3: 验证SQL语句
	fmt.Println("\n步骤3: 验证SQL语句...")
	if err := imp.validator.ValidateStatements(statements); err != nil {
		fmt.Printf("⚠ 验证发现问题: %v\n", err)
		stats.Errors = append(stats.Errors, err.Error())
	}

	if imp.validator.HasWarnings() {
		warnings := imp.validator.GetWarnings()
		stats.Warnings = append(stats.Warnings, warnings...)
		fmt.Printf("⚠ 发现 %d 个警告\n", len(warnings))
	}

	if !imp.validator.HasErrors() {
		fmt.Println("✓ SQL语句验证通过")
	}

	// 步骤4: 转换SQL语句
	fmt.Println("\n步骤4: 转换SQL语句...")
	convertedStatements, conversionWarnings, err := imp.convertStatements(statements)
	if err != nil {
		return fmt.Errorf("转换SQL语句失败: %v", err)
	}
	stats.Warnings = append(stats.Warnings, conversionWarnings...)
	fmt.Printf("✓ 成功转换 %d 条语句\n", len(convertedStatements))

	// 步骤5: 连接数据库
	fmt.Println("\n步骤5: 连接数据库...")
	connStr := imp.buildConnectionString()
	exec, err := executor.NewStatementExecutor(connStr)
	if err != nil {
		return fmt.Errorf("连接数据库失败: %v", err)
	}
	defer exec.Close()
	imp.executor = exec

	// 获取数据库信息
	dbInfo, err := exec.GetDatabaseInfo()
	if err != nil {
		fmt.Printf("⚠ 无法获取数据库信息: %v\n", err)
	} else {
		fmt.Printf("✓ 已连接到数据库: %s (用户: %s)\n", dbInfo["database"], dbInfo["user"])
	}

	// 步骤6: 执行SQL语句
	fmt.Println("\n步骤6: 执行SQL语句...")
	if err := exec.ExecuteStatementsWithOrder(statements, convertedStatements); err != nil {
		stats.Errors = append(stats.Errors, err.Error())
		return fmt.Errorf("执行SQL语句失败: %v", err)
	}
	stats.SuccessStatements = len(convertedStatements)
	fmt.Println("✓ 所有语句执行成功")

	// 完成统计
	stats.EndTime = time.Now()
	stats.Duration = stats.EndTime.Sub(stats.StartTime)
	stats.StatementStats = imp.parser.GetStats()

	// 显示最终报告
	imp.printFinalReport(stats)

	return nil
}

// validateConnectionParams 验证连接参数
func (imp *Importer) validateConnectionParams() error {
	if err := validator.ValidateConnectionString(imp.connectionString); err != nil {
		return err
	}

	if err := validator.ValidateCredentials(imp.username, imp.password); err != nil {
		return err
	}

	return nil
}

// convertStatements 转换SQL语句
func (imp *Importer) convertStatements(statements []parser.SQLStatement) ([]string, []string, error) {
	var convertedStatements []string
	var allWarnings []string

	for _, stmt := range statements {
		converted, err := imp.converter.Convert(stmt, nil)
		if err != nil {
			return nil, nil, fmt.Errorf("转换语句失败 (第%d行): %v", stmt.Line, err)
		}

		if strings.TrimSpace(converted) != "" {
			convertedStatements = append(convertedStatements, converted)
		}

		// 收集转换警告
		warnings := imp.converter.GetConversionWarnings(stmt)
		for _, warning := range warnings {
			allWarnings = append(allWarnings, fmt.Sprintf("第%d行: %s", stmt.Line, warning))
		}
	}

	return convertedStatements, allWarnings, nil
}

// buildConnectionString 构建数据库连接字符串
func (imp *Importer) buildConnectionString() string {
	// 解析连接字符串 host:port/database
	parts := strings.Split(imp.connectionString, "/")
	if len(parts) != 2 {
		return ""
	}

	hostPort := parts[0]
	database := parts[1]

	hostPortParts := strings.Split(hostPort, ":")
	if len(hostPortParts) != 2 {
		return ""
	}

	host := hostPortParts[0]
	port := hostPortParts[1]

	// 构建PostgreSQL连接字符串
	return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
		host, port, imp.username, imp.password, database)
}

// printFinalReport 打印最终报告
func (imp *Importer) printFinalReport(stats *ImportStats) {
	fmt.Println("\n" + strings.Repeat("=", 50))
	fmt.Println("=== KWDB导入工具统计信息 ===")
	fmt.Println(strings.Repeat("=", 50))

	// 基本统计
	for statType, count := range stats.StatementStats {
		if count > 0 {
			fmt.Printf("%s: %d\n", statType, count)
		}
	}

	fmt.Printf("总语句数: %d\n", stats.TotalStatements)
	fmt.Printf("成功执行: %d\n", stats.SuccessStatements)
	fmt.Printf("执行失败: %d\n", stats.FailedStatements)

	// 时间统计
	fmt.Printf("\n开始时间: %s\n", stats.StartTime.Format("2006-01-02 15:04:05"))
	fmt.Printf("结束时间: %s\n", stats.EndTime.Format("2006-01-02 15:04:05"))
	fmt.Printf("总耗时: %v\n", stats.Duration)

	// 警告信息
	if len(stats.Warnings) > 0 {
		fmt.Printf("\n⚠ 警告信息 (%d条):\n", len(stats.Warnings))
		for i, warning := range stats.Warnings {
			if i < 10 { // 只显示前10条警告
				fmt.Printf("  %d. %s\n", i+1, warning)
			}
		}
		if len(stats.Warnings) > 10 {
			fmt.Printf("  ... 还有 %d 条警告\n", len(stats.Warnings)-10)
		}
	}

	// 错误信息
	if len(stats.Errors) > 0 {
		fmt.Printf("\n❌ 错误信息 (%d条):\n", len(stats.Errors))
		for i, err := range stats.Errors {
			if i < 5 { // 只显示前5条错误
				fmt.Printf("  %d. %s\n", i+1, err)
			}
		}
		if len(stats.Errors) > 5 {
			fmt.Printf("  ... 还有 %d 条错误\n", len(stats.Errors)-5)
		}
	}

	fmt.Println(strings.Repeat("=", 50))

	if len(stats.Errors) == 0 {
		fmt.Println("🎉 导入完成！所有语句执行成功。")
	} else {
		fmt.Println("⚠ 导入完成，但存在错误，请检查上述错误信息。")
	}
}

// GetVersion 获取工具版本
func GetVersion() string {
	return "1.2.0"
}

// GetSupportedFeatures 获取支持的特性列表
func GetSupportedFeatures() []string {
	return []string{
		"CREATE DATABASE - 数据库创建",
		"DROP DATABASE - 数据库删除",
		"USE - 数据库选择",
		"CREATE TABLE - 表创建",
		"DROP TABLE - 表删除",
		"CREATE INDEX - 索引创建",
		"CREATE VIEW - 视图创建",
		"INSERT - 数据插入",
		"CREATE SEQUENCE - 序列创建",
		"数据类型自动转换",
		"MySQL特性移除",
		"执行顺序优化",
		"详细统计报告",
	}
}
